﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace iNet.Media
{
	/// <summary>
	/// 表示一個二維大小。
	/// </summary>
	/// <typeparam name="T">表示高度與寬度的資料型別。</typeparam>
	public struct Size<T> where T : IComparable<T>
	{
		#region 建構子
		/// <summary>
		/// 初始化 Size 結構欄位。
		/// </summary>
		/// <param name="width">寬度。</param>
		/// <param name="height">高度。</param>
		public Size(T width, T height)
			: this()
		{
			this.Width = width;
			this.Height = height;
		}
		#endregion
		#region Equals
		/// <summary>
		/// 確認是否與指定的物件相等。
		/// </summary>
		/// <param name="obj">指定的物件。</param>
		/// <returns>True 表示寬與高皆相等，False 表示不相等。</returns>
		public override bool Equals(object obj)
		{
			if (obj is Size<T>)
				return this.Equals((Size<T>)obj);
			return false;
		}
		/// <summary>
		/// 確認是否與指定的 Size 相等。
		/// </summary>
		/// <param name="size">指定的 Size。</param>
		/// <returns>True 表示寬與高皆相等，False 表示不相等。</returns>
		public bool Equals(Size<T> size)
		{
			return (this == size);
		}
		#endregion
		#region Height
		/// <summary>
		/// 取得或設定高度。
		/// </summary>
		public T Height { get; set; }
		#endregion
		#region IsEmpty
		/// <summary>
		/// 取得值以確認是否含有空的寬度或高度。
		/// </summary>
		public bool IsEmpty
		{
			get
			{
				return (this.Width.Equals(default(T)) || this.Height.Equals(default(T)));
			}
		}
		#endregion
		#region operator ==
		public static bool operator ==(Size<T> x, Size<T> y)
		{
			return (x.Width.Equals(y.Width) && x.Height.Equals(y.Height));
		}
		#endregion
		#region operator !=
		public static bool operator !=(Size<T> x, Size<T> y)
		{
			return (!x.Width.Equals(y.Width) || !x.Height.Equals(y.Height));
		}
		#endregion
		#region ToString
		/// <summary>
		/// 取得表示此結構的字串。
		/// </summary>
		/// <returns>表示此結構的字串。</returns>
		public override string ToString()
		{
			return (this.Width + "x" + this.Height);
		}
		#endregion
		#region Width
		/// <summary>
		/// 取得或設定寬度。
		/// </summary>
		public T Width { get; set; }
		#endregion
	}

	/// <summary>
	/// 提供 Size&lt;T&gt; 相關的延伸方法。
	/// </summary>
	public static class SizeExtensions
	{
		#region ToDoubleSize
		/// <summary>
		/// 將指定的 Size&lt;Int32&gt; 轉換成對應的 Size&lt;Double&gt;。
		/// </summary>
		/// <param name="size">指定的 Size&lt;Int32&gt;。</param>
		/// <returns>對應的 Size&lt;Double&gt;。</returns>
		public static Size<double> ToDoubleSize(this Size<int> size)
		{
			return new Size<double>(size.Width, size.Height);
		}
		#endregion
		#region ToInt32Size
		/// <summary>
		/// 將指定的 Size&lt;Double&gt; 轉換成對應的 Size&lt;Int32&gt;。
		/// </summary>
		/// <param name="size">指定的 Size&lt;Double&gt;。</param>
		/// <returns>對應的 Size&lt;Int32&gt;。</returns>
		public static Size<int> ToInt32Size(this Size<double> size)
		{
			return new Size<int>((int)size.Width, (int)size.Height);
		}
		#endregion
	}
}
